home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
001-025
/
disk_018
/
multidim
/
multidim.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
13KB
|
436 lines
/*************************************************************************
* Version 0.0 MULTIDIM.C - Multi-dimensional rotation 12-Mar-86 *
* Commodore Amiga Main Module MULTIDIM.C *
*************************************************************************
* Copyright (c) 1986, Robert S. French *
* --------------------------------------------------------------------- *
* This program has been placed in the public domain. A limited *
* license is hereby granted for the unlimited use and distribution of *
* this program, provided it is not used for commercial or profit- *
* making purposes. Thank you. *
*************************************************************************
* Author information: | Disclaimer: *
* | *
* Name: Robert S. French | The author takes no responsibil- *
* USnail: 2740 Frankfort Avenue | ity for damages incurred during *
* Louisville, KY 40206 | the use of this program. *
* Phone: (502) 897-5096 \-----------------------------------*
* ARPA: French#Robert%d@LLL-MFE UUCP: ihnp4!ptsfa!well!french *
*************************************************************************
* Please send any comments, suggestions, or bugs to one of the above *
* addresses. *
*************************************************************************
* Comments *
* ======== *
* *
* Please note that I have very little background in multi-dimensional *
* theory. This program is not meant to be a scientific representation *
* of higher universes, just something kinda neat to look at. I'm sure *
* that there are mathematical problems, such as rotational direction *
* in the higher planes. "A" etc. are used for lack of better names. *
* Hold the joystick right and press the button to end, or left and *
* press for automatic demo. Feel free to hack this program up as much *
* as you like. One of the things I'd like to add is double-buffering. *
*************************************************************************/
/* Lots of include files! */
#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <devices/keymap.h>
#include <devices/gameport.h>
#include <devices/inputevent.h>
#include <graphics/copper.h>
#include <graphics/display.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/view.h>
#include <graphics/gels.h>
#include <graphics/regions.h>
#include <hardware/blit.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <stdio.h>
/* Some definitions... */
#define MAXDIM 6
#define MAXPOINTS 64
#define MAXEDGES 250
#define XSCALE 145
#define YSCALE 60
#define XCENTER 320
#define YCENTER 100
/* Fast-Floating-Point Definitions... */
extern int SPFix();
extern int SPFlt();
extern int SPCmp();
extern int SPTst();
extern int SPAbs();
extern int SPNeg();
extern int SPAdd();
extern int SPSub();
extern int SPMul();
extern int SPDiv();
extern int SPAtan();
extern int SPSin();
extern int SPCos();
extern int SPTan();
extern int SPSincos();
extern int SPSinh();
extern int SPCosh();
extern int SPTanh();
extern int SPExp();
extern int SPLog();
extern int SPPow();
extern int SPSqrt();
extern int SPTieee();
extern int SPFieee();
/* Other external functions... */
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
/* And some global graphics stuff... */
struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Screen *scrn = NULL;
struct NewScreen newscreen;
struct RastPort *rp = NULL;
struct ViewPort *vp = NULL;
/* And some more global stuff... */
int MathBase = NULL, MathTransBase = NULL;
struct IOStdReq *joystick_io_request = NULL;
struct InputEvent joystick_data;
union kludge {
float f;
int i;
} points[MAXPOINTS][MAXDIM], xscale, yscale, sqrt2, const2, const15,
recip2sqrt2;
int st_edge[MAXEDGES], end_edge[MAXEDGES], xpoints[MAXPOINTS],
ypoints[MAXPOINTS];
int num_points,num_edges,num_dim,alldim;
/* And the real thing... */
main(argc,argv)
int argc;
char *argv[];
{
int i,j,k,num_change,axis1,axis2,autorot,autocount;
union kludge angle,nangle,pi;
char *s;
if (argc < 2)
abort("Usage: multidim n {D} where n is the number of dimensions");
num_dim = atoi(argv[1]);
if (num_dim < 2 || num_dim > MAXDIM)
abort("Illegal number of dimensions");
alldim = 1;
if (argc == 3 && toupper(argv[2][0]) == 'D')
alldim = 0;
if ((MathBase = OpenLibrary("mathffp.library")) == NULL)
abort("Can't open mathffp.library!");
if ((MathTransBase = OpenLibrary("mathtrans.library")) == NULL)
abort("Can't open mathtrans.library!");
xscale.i = SPFlt(XSCALE);
yscale.i = SPFlt(YSCALE);
const2.i = SPFlt(2);
const15.i = SPDiv(SPFlt(2),SPFlt(3));
sqrt2.i = SPSqrt(const2.i);
recip2sqrt2.i = SPDiv(SPMul(SPFlt(2),sqrt2.i),SPFlt(1));
num_points = 1 << num_dim;
/* Figure out vertices of n-dimensional "cube" */
for (i=0;i<num_points;i++)
for (j=0;j<num_dim;j++)
if (i & (1 << j))
points[i][j].i = SPFlt(1);
else
points[i][j].i = SPFlt(-1);
/* Figure out edges */
num_edges = 0;
for (i=0;i<num_points-1;i++)
for (j=i+1;j<num_points;j++) {
num_change = 0;
for (k=0;k<num_dim;k++)
if (points[i][k].i != points[j][k].i)
num_change++;
if (num_change == 1) {
st_edge[num_edges] = i;
end_edge[num_edges] = j;
num_edges++;
}
}
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0)) == NULL)
abort("Can't open Intuition.Library!\n");
if ((GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 0)) == NULL)
abort("Can't open Graphics.Library!\n");
open_joystick();
/* values for new screen */
newscreen.LeftEdge = 0;
newscreen.TopEdge = 0;
newscreen.Width = 640;
newscreen.Height = 200;
newscreen.Depth = 1;
newscreen.DetailPen = 0;
newscreen.BlockPen = 1;
newscreen.ViewModes = HIRES;
newscreen.Type = CUSTOMSCREEN;
newscreen.Font = NULL;
newscreen.DefaultTitle = "";
newscreen.Gadgets = NULL;
scrn = (struct Screen *)OpenScreen(&newscreen);
if (scrn == 0)
abort("Can't open new screen!\n");
vp = &(scrn->ViewPort);
rp = &(scrn->RastPort);
SetAPen(rp,0);
RectFill(rp,0,0,639,199);
SetRGB4(vp,0,0,0,0);
SetRGB4(vp,1,0xb,0,0);
SetAPen(rp,1);
SetBPen(rp,0);
SetDrMd(rp,JAM2);
Move(rp,0,9);
Text(rp,"Plane: X Y",10);
Move(rp,550,9);
Text(rp,"R. French",9);
pi.f = 3.1415926535;
pi.i = SPFieee(pi.i);
angle.i = SPMul(SPDiv(SPFlt(180),pi.i),SPFlt(5));
nangle.i = SPNeg(angle.i);
axis1 = 0;
axis2 = 1;
autorot = autocount = 0;
s = " ";
draw();
while(1) {
DoIO(joystick_io_request);
if (joystick_data.ie_Y == 1 && !autorot) {
rotate(axis1,axis2,nangle.i);
draw();
}
else if (joystick_data.ie_Y == -1 || autorot) {
rotate(axis1,axis2,angle.i);
draw();
}
if (autorot) autocount = (autocount + 1) % 33;
if (joystick_data.ie_Code == IECODE_LBUTTON || autocount == 32) {
if (joystick_data.ie_Code == IECODE_LBUTTON)
autorot = autocount = 0;
if (joystick_data.ie_X == 1)
abort("All done!");
if (joystick_data.ie_X == -1)
autorot = 1;
axis2++;
if (axis2 > num_dim-1) {
axis1++;
if (axis1 > num_dim-2)
axis1 = 0;
axis2 = axis1 + 1;
}
SetAPen(rp,0);
RectFill(rp,56,0,85,9);
SetAPen(rp,1);
Move(rp,56,9);
s[0] = (axis1 < 3) ? 'X'+axis1 : 'A'+axis1-3;
s[2] = (axis2 < 3) ? 'X'+axis2 : 'A'+axis2-3;
Text(rp,s,3);
}
}
}
abort(s)
char *s;
{
puts(s);
if (joystick_io_request) close_joystick();
if (scrn) CloseScreen(scrn);
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (MathTransBase) CloseLibrary(MathTransBase);
if (MathBase) CloseLibrary(MathBase);
exit(20);
}
draw()
{
int i,dim;
union kludge z;
for (i=0;i<num_points;i++) {
z.i = SPFlt(1);
if (num_dim > 2)
if (alldim)
for (dim=num_dim-1;dim>=2;--dim)
z.i = SPMul(SPAdd(SPMul(points[i][dim].i,recip2sqrt2.i),
const15.i),z.i);
else
z.i = SPAdd(SPMul(points[i][num_dim-1].i,recip2sqrt2.i),
const15.i);
xpoints[i] = SPFix(SPMul(SPDiv(z.i,points[i][0].i),xscale.i))+XCENTER;
ypoints[i] = SPFix(SPMul(SPDiv(z.i,points[i][1].i),yscale.i))+YCENTER;
}
SetAPen(rp,0);
RectFill(rp,0,10,639,199);
SetAPen(rp,1);
SetDrMd(rp,JAM1);
for (i=0;i<num_edges;i++) {
Move(rp,xpoints[st_edge[i]],ypoints[st_edge[i]]);
Draw(rp,xpoints[end_edge[i]],ypoints[end_edge[i]]);
}
}
rotate(p1,p2,a)
int p1,p2,a;
{
int i;
union kludge ang,thesin,thecos,temp1,temp2;
ang.i = a;
thesin.i = SPSin(ang.i);
thecos.i = SPCos(ang.i);
for (i=0;i<num_points;i++) {
temp1.i = SPSub(SPMul(points[i][p2].i,thesin.i),
SPMul(points[i][p1].i,thecos.i));
temp2.i = SPAdd(SPMul(points[i][p2].i,thecos.i),
SPMul(points[i][p1].i,thesin.i));
points[i][p1].i = temp1.i;
points[i][p2].i = temp2.i;
}
}
open_joystick()
{
struct MsgPort *joystick_msg_port;
/* provide a port for the IO request/response */
joystick_msg_port = CreatePort("thejoystickport",0);
if(joystick_msg_port == 0)
abort("Can't create joystick port");
/* make an io request block for communicating with the joystick device */
joystick_io_request = CreateStdIO(joystick_msg_port);
if(joystick_io_request == 0)
abort("Can't create joystick I/O request block");
/* open the gameport device for access, unit 1 is right port */
if(OpenDevice("gameport.device",1,joystick_io_request,0))
abort("Can't open joystick device");
/* set the device type to absolute joystick */
if (set_controller_type(GPCT_ABSJOYSTICK) != 0)
abort("Can't set controller type");
/* trigger on button-down, button-up, front, back, left, right, center */
if (set_controller_trigger(GPTF_UPKEYS+GPTF_DOWNKEYS,1,1,1) != 0)
abort("Can't set controller trigger");
/* SETUP THE IO MESSAGE BLOCK FOR THE ACTUAL DATA READ */
/* gameport.device replies to this task */
joystick_io_request->io_Message.mn_ReplyPort = joystick_msg_port;
/* from now on, just read input events */
joystick_io_request->io_Command = GPD_READEVENT;
/* into the input buffer, one at a time. */
joystick_io_request->io_Data = (APTR)&joystick_data;
/* read num events each time we go back to the joystickport */
joystick_io_request->io_Length = sizeof(joystick_data);
}
close_joystick()
{
/* close up joystick device */
CloseDevice(joystick_io_request);
/* clean up */
DeletePort(joystick_io_request->io_Message.mn_ReplyPort);
DeleteStdIO(joystick_io_request);
}
int set_controller_type(type)
BYTE type;
{
joystick_io_request->io_Command = GPD_SETCTYPE;
joystick_io_request->io_Length = 1;
/* set type of controller to "type" */
joystick_io_request->io_Data = (APTR)&type;
return(DoIO(joystick_io_request));
}
int set_controller_trigger(keys,timeout,xdelta,ydelta)
UWORD keys,timeout,xdelta,ydelta;
{
struct GamePortTrigger gpt;
joystick_io_request->io_Command = GPD_SETTRIGGER;
joystick_io_request->io_Length = sizeof(gpt);
joystick_io_request->io_Data = (APTR)&gpt;
gpt.gpt_Keys = keys;
gpt.gpt_Timeout = timeout;
gpt.gpt_XDelta = xdelta;
gpt.gpt_YDelta = ydelta;
return(DoIO(joystick_io_request));
}